import {initRender} from "./render";
import {initState} from "./state";
import {mount} from "../../platform/web/mount";
import {isDef, mergeOptions} from "../util";
import {initLifeCycle, invokeLifeCycleHook} from "./lifecycle";
import {initEvents} from "./events";

export function initMixin (Reactive) {

    Reactive.prototype._init = function (options) {

        const vm = this;

        vm._self = vm;
        if (isDef(vm.constructor.options)) {
            initComponentInstanceOptions(
                vm.constructor,
                options || {},
                vm);
        }

        // initLifeCycle 对该组件的生命周期钩子函数进行处理
        initLifeCycle(vm);

        // 调用生命周期回调 beforeCreate
        invokeLifeCycleHook(vm, 'beforeCreate');

        // initRender 编译得到渲染函数
        initRender(vm);
        // initEvents 对该组件的监听事件进行了初始化和事件代理
        initEvents(vm);
        // initState 对数据进行了观察者绑定
        initState(vm);

        // 调用生命周期回调 created
        invokeLifeCycleHook(vm, 'created');

        // 如果存在 options 中存在配置 el
        // 则说明不是组件, 挂载模板内容
        if (vm.$options.el) {
            mount(vm);
        }
    }
}

/**
 * 生成组件实例配置
 * 将组件类的配置与实例的配置合并
 * @param {Function} componentConstructor 组件类配置
 * @param {Object} options 实例配置
 * @param {Reactive} vm 组件实例
 */
function initComponentInstanceOptions (componentConstructor, options, vm) {
    const componentConstructorOptions = componentConstructor.options;
    vm.$options = mergeOptions(componentConstructorOptions, options);
}
